package tp1;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.UnknownHostException;
import javax.swing.JOptionPane;
import javax.swing.Timer;

import tp1.TrieurListeForme.SorteTri;

@SuppressWarnings("serial")
public class AfficheurFormes extends Canvas implements ActionListener {
	private final int MAX_ITEM_AFFICHE = 10;
	private int index = 0;
	private ListeChainee<Forme> formes = new ListeChainee<Forme>();
	private Connexion c;
	private Timer updateTimer;
	private Main parent;
	private TrieurListeForme trieur = new TrieurListeForme();
	private SorteTri sorteTri = SorteTri.Aucun;

	public boolean estConnecte() {
		return c != null;
	}

	public boolean estActive() {
		return updateTimer.isRunning();
	}

	public AfficheurFormes(Main parent) {
		updateTimer = new Timer(1000, this);
		this.parent = parent;
	}

	/**
	 * Démarre la connection au serveur. Si une connexion existe déjà, on
	 * redémarre la connection. Sinon, une nouvelle connexion est crée.
	 * 
	 * @param infosConnection
	 *            La chaine contant les informations pour la connexion au
	 *            serveur
	 * @param arreterAMax
	 *            Arrete ou non la connexion lorsque la liste est pleine
	 * @throws NumberFormatException
	 *             Le numéro de port n'est pas bon
	 * @throws UnknownHostException
	 * @throws IOException
	 * @throws InterruptedException
	 */
	public void demarrer(String nom, String port, boolean arreterAMax) throws NumberFormatException, UnknownHostException, IOException, InterruptedException {
		if (arreterAMax) {
			c = new Connexion(nom, Integer.parseInt(port));
			while (formes.obtenirLargeur() != MAX_ITEM_AFFICHE) {
				mettreAJour(c.pousserObtenir());
			}
			if(sorteTri != SorteTri.Aucun){
				trier(sorteTri);
			}
			c.fermer();
			c = null;
			return;
		}

		if (c != null) {
			updateTimer.start();
		} else {
			c = new Connexion(nom, Integer.parseInt(port));
			updateTimer.start();
		}
	}

	/**
	 * Arrete l'envoi de commande
	 */
	public void pause() {
		updateTimer.stop();
	}

	/**
	 * Arrete et ferme la connexion au serveur
	 */
	public void arreter() {
		updateTimer.stop();
		formes.nettoyer();
		index = 0;
		this.getGraphics().clearRect(0, 0, this.getWidth(), this.getHeight());
		if (c != null) {
			c.fermer();
		}
		c = null;
	}

	/**
	 * Mets à jour la liste de forme à dessiner et redessine le canvas
	 * 
	 * @param cmd
	 *            La commande recu du serveur
	 */
	private void mettreAJour(String cmd) {
		if (index == MAX_ITEM_AFFICHE) {
			index = 0;
		}
		if (formes.obtenirLargeur() != 10) {
			formes.ajouter(Forme.creerForme(cmd));
		} else {
			formes.ajouter(Forme.creerForme(cmd), index);
		}
		index++;
		repaint();
	}

	/**Tri la liste de forme selon le critere de tri
	 * @param tri Le critere de tri
	 */
	public void trier(SorteTri tri){
		sorteTri = tri;
		formes = trieur.trierListe(formes, sorteTri);
		repaint();
	}

	public void paint(Graphics g) {
		for (int i = 0; i < formes.obtenirLargeur(); i++) {
			Forme f = formes.obtenir(i);
			if (f != null) {
				g.setColor(f.obtenirCouleur());
				if (sorteTri == SorteTri.Aucun) {
					if (f instanceof Rectangle) {
						Rectangle rect = (Rectangle) f;
						g.fillRect(rect.obtenirPosX1(), rect.obtenirPosY1(), rect.obtenirLargeur(), rect.obtenirHauteur());
					} else if (f instanceof Ovale) {
						Ovale cerc = (Ovale) f;
						g.fillOval(cerc.obtenirCentreX(), cerc.obtenirCentreY(), cerc.obtenirLargeur(), cerc.obtenirHauteur());
					} else if (f instanceof Ligne) {
						Ligne ligne = (Ligne) f;
						g.drawLine(ligne.obtenirPosX1(), ligne.obtenirPosY1(), ligne.obtenirPosX2(), ligne.obtenirPosY2());

					}
				} else {
					if (f instanceof Rectangle) {
						Rectangle rect = (Rectangle) f;
						g.fillRect(i * 40, i * 40, rect.obtenirLargeur(), rect.obtenirHauteur());
					} else if (f instanceof Ovale) {
						Ovale cerc = (Ovale) f;
						g.fillOval(i * 40, i * 40, cerc.obtenirLargeur(), cerc.obtenirHauteur());
					} else if (f instanceof Ligne) {
						Ligne ligne = (Ligne) f;
						g.drawLine(i * 40, i * 40, ligne.obtenirPosX2() - (ligne.obtenirPosX1() + i * 40), ligne.obtenirPosY2() - (ligne.obtenirPosY1() + i * 40));

					}
					// DEBUG
					g.setColor(Color.BLACK);
					g.drawString(Integer.toString(f.obtenirNseq()), i * 40, i * 40);
				}

			}
		}
	}

	@Override
	public void actionPerformed(ActionEvent ae) {
		// action pour le timer
		try {
			mettreAJour(c.pousserObtenir());
		} catch (IOException ex) {
			arreter();
			JOptionPane.showMessageDialog(this, "Le serveur a ete ferme", "Connexion perdue", JOptionPane.ERROR_MESSAGE);
			//parent.majEtatMenu();
		}
	}
}
